#include "ShotCutEffect.h"
#include <QFontDatabase>

//********************************************* Mask Effect ******************************************************************//
MaskEffect::MaskEffect(const JsonMaskEffect& JsonData)
{
    for(JsonMaskEffect::MaskEffectInfo* MaskInfo : JsonData.JsonMaskEffectArray)
    {
        Mask* NewMask = SetupEffectByName(MaskInfo->Type, MaskInfo->TransitionIn, MaskInfo->ZoomRate * (MaskInfo->EndTime - MaskInfo->BeginTime));
        MaskEffectArray.push_back(make_pair(shared_ptr<JsonMaskEffect::MaskEffectInfo>(MaskInfo), shared_ptr<Mask>(NewMask)));
    }

    SetProPerty();
}

void MaskEffect::SetProPerty()
{
    for(auto MaskEffectItem : MaskEffectArray)
    {
        double TimeSpeed = MaskEffectItem.first->ZoomRate;
        MaskEffectItem.second->Layer(MaskEffectItem.first->Layer);
        MaskEffectItem.second->Position(MaskEffectItem.first->PositionTime);
        MaskEffectItem.second->Start(TimeSpeed * MaskEffectItem.first->BeginTime);
        MaskEffectItem.second->End(TimeSpeed * MaskEffectItem.first->EndTime);
    }
}

Mask* MaskEffect::SetupEffectByName(std::string EffectName, bool TransitionIn, double DurationTime)
{
    if(TransitionIn)
    {
        return EffectTransitionIn(MaskEffectFile[EffectName], DurationTime);
    }
    else
    {
        return EffectTransitionOut(MaskEffectFile[EffectName], DurationTime);
    }
}

Mask* MaskEffect::EffectTransitionIn(std::string MaskFile, double DurationTime)
{
    QtImageReader* MaskRender = new QtImageReader(MaskFile);
    std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
    
    double DurationFrame = round(DurationTime * Global->GetFps()) + 1;
    Keyframe* brightness = new Keyframe();
    brightness->AddPoint(0.0, 1.0, BEZIER);
    brightness->AddPoint(DurationFrame, -1.0, BEZIER);
    Keyframe* contrast = new Keyframe(3.0);
    return new Mask(MaskRender, *brightness, *contrast);
}

Mask* MaskEffect::EffectTransitionOut(std::string MaskFile, double DurationTime)
{
    QtImageReader* MaskRender = new QtImageReader(MaskFile);
    std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
    
    double DurationFrame = round(DurationTime * Global->GetFps()) + 1;
    Keyframe* brightness = new Keyframe();
    brightness->AddPoint(0.0, -1.0, BEZIER);
    brightness->AddPoint(DurationFrame, 1.0, BEZIER);
    Keyframe* contrast = new Keyframe(3.0);
    return new Mask(MaskRender, *brightness, *contrast);
}

//********************************************* Image Effect ******************************************************************//
ImageEffect::ImageEffect(const JsonImageEffect& JsonData)
{
    for(JsonImageEffect::ImageEffectInfo* ImageInfo : JsonData.JsonImageEffectArray)
    {
        ImageEffectArray.push_back(make_pair(shared_ptr<JsonImageEffect::ImageEffectInfo>(ImageInfo), make_shared<Clip>(ImageInfo->File)));
    }

    SetProPerty();
}

void ImageEffect::SetProPerty()
{
    std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
    float SrcVideoWidth = Global->GetVideoWidth(), SrcVideoHeight = Global->GetVideoHeight();
    
    for(auto ImageEffectItem : ImageEffectArray)
    {
        double TimeSpeed = ImageEffectItem.first->ZoomRate;
        ImageEffectItem.second->Layer(ImageEffectItem.first->Layer);
        ImageEffectItem.second->Position(ImageEffectItem.first->PositionTime);
        ImageEffectItem.second->Start(TimeSpeed * ImageEffectItem.first->BeginTime);
        ImageEffectItem.second->End(TimeSpeed * ImageEffectItem.first->EndTime);
        ImageEffectItem.second->time.AddPoint(0, 0, openshot::LINEAR);
        ImageEffectItem.second->time.AddPoint(ImageEffectItem.first->VideoFrame * TimeSpeed, ImageEffectItem.first->VideoFrame, openshot::LINEAR);
        ImageEffectItem.second->scale_x =ImageEffectItem.first->ScaleX;
        ImageEffectItem.second->scale_y =ImageEffectItem.first->ScaleY;
        ImageEffectItem.second->rotation =ImageEffectItem.first->Rotation;
        ImageEffectItem.second->location_x =ImageEffectItem.first->CoordX / SrcVideoWidth - 0.5f;
        ImageEffectItem.second->location_y =ImageEffectItem.first->CoordY / SrcVideoHeight - 0.5f;
        ImageEffectItem.second->alpha =ImageEffectItem.first->Alpha;
    }
}

//********************************************* Font Effect ******************************************************************//
FontEffect::FontEffect(const JsonFontEffect& JsonData)
{
    for(JsonFontEffect::FontEffectInfo* FontInfo : JsonData.JsonFontEffectArray)
    {
        FontEffectArray.push_back(make_pair(shared_ptr<JsonFontEffect::FontEffectInfo>(FontInfo), make_shared<Caption>()));
    }

    SetProPerty();
}

void FontEffect::SetProPerty()
{
    std::shared_ptr<GlobalData> Global = GlobalData::GetGlobalData();
    float SrcVideoWidth = Global->GetVideoWidth(), SrcVideoHeight = Global->GetVideoHeight();
    for(auto FontEffectItem : FontEffectArray)
    {
        QString FontFamily = "";
        int FontID = -1;

        if(!FontEffectItem.first->FontFile.empty())
        {
            FontID = QFontDatabase::addApplicationFont(QString::fromStdString(FontEffectItem.first->FontFile));
            if(FontID != -1)
            {
                FontFamily = QFontDatabase::applicationFontFamilies(FontID).at(0);
            }
            else
            {
                std::cout << "Filed to load: " << FontEffectItem.first->FontFile << std::endl;
            }
        }
        
        double TimeSpeed = FontEffectItem.first->ZoomRate;
        FontEffectItem.second->Layer(FontEffectItem.first->Layer);
        FontEffectItem.second->Position(FontEffectItem.first->PositionTime);
        FontEffectItem.second->Start(TimeSpeed * FontEffectItem.first->BeginTime);
        FontEffectItem.second->End(TimeSpeed * FontEffectItem.first->EndTime);
        FontEffectItem.second->CaptionText("00:00:00:000 --> 01:00:00:000\n" + FontEffectItem.first->Text);
        FontEffectItem.second->color = Color(FontEffectItem.first->Color);
        FontEffectItem.second->stroke = Color(FontEffectItem.first->StrokeColor);
        FontEffectItem.second->stroke_width = FontEffectItem.first->StrokeWidth;
        FontEffectItem.second->font_size = FontEffectItem.first->FontSize;
        if(!FontFamily.toStdString().empty())
        {
            FontEffectItem.second->font_name = FontFamily.toStdString();
        }
        else
        {
            FontEffectItem.second->font_name = FontEffectItem.first->FontType;
        }
        FontEffectItem.second->left = FontEffectItem.first->CoordX / SrcVideoWidth - 0.5f;
        FontEffectItem.second->top = FontEffectItem.first->CoordY / SrcVideoHeight;
        FontEffectItem.second->font_alpha = FontEffectItem.first->Alpha;
    }
}
